import { IAgentService, IAgentCallbacks, AgentToolRequest } from './IAgentService';
import { Attachment } from '../types/types';

/**
 * Mock Agent 服务实现
 * 用于测试 "UI -> Controller -> Service -> Tool -> Service -> UI" 的全链路流程
 * 
 * 支持的测试场景:
 * 1. 关键词 "命令"/"command" -> 触发 executeCommand 工具调用
 * 2. 关键词 "文件" -> 显示附件信息
 * 3. 关键词 "连续"/"多个" -> 触发多个工具调用
 * 4. 关键词 "拒绝" -> 触发工具确认测试
 * 5. 其他 -> 普通对话
 */
export class MockAgentService implements IAgentService {
    
    private conversationHistory: Array<{ role: string; content: string }> = [];
    
    async initialize(): Promise<void> {
        console.log('[MockAgentService] ✅ Initialized. Ready for testing!');
        this.conversationHistory = [];
    }

    async sendMessage(
        text: string,
        attachments: Attachment[] | undefined,
        callbacks: IAgentCallbacks
    ): Promise<void> {
        // 记录对话历史
        this.conversationHistory.push({ role: 'user', content: text });
        
        // 模拟网络延迟
        await this.sleep(400);

        const lowerText = text.toLowerCase();

        // ========================================
        // 场景1: 测试 executeCommand 工具调用
        // ========================================
        if (lowerText.includes('命令') || lowerText.includes('command')) {
            await this.handleCommandScenario(text, callbacks);
            return;
        }

        // ========================================
        // 场景2: 测试附件处理
        // ========================================
        if (lowerText.includes('文件') || lowerText.includes('附件')) {
            await this.handleFileScenario(text, attachments, callbacks);
            return;
        }

        // ========================================
        // 场景3: 测试多个工具连续调用
        // ========================================
        if (lowerText.includes('连续') || lowerText.includes('多个')) {
            await this.handleMultipleToolsScenario(callbacks);
            return;
        }

        // ========================================
        // 场景4: 测试需要确认的工具
        // ========================================
        if (lowerText.includes('确认') || lowerText.includes('拒绝')) {
            await this.handleConfirmationScenario(callbacks);
            return;
        }

        // ========================================
        // 场景5: 普通对话(兜底)
        // ========================================
        await this.handleNormalConversation(text, callbacks);
    }

    /**
     * 处理工具执行结果
     * 当 Controller 执行完工具后，会调用此方法
     */
    async processToolResults(
        toolResults: { toolCallId: string; output: string }[],
        callbacks: IAgentCallbacks
    ): Promise<void> {
        await this.sleep(600);
        
        // 模拟 AI 对工具结果的分析
        const intro = '\n\n✅ 工具执行完毕！让我分析一下结果：\n\n';
        await this.streamText(intro, callbacks, 20);

        for (const res of toolResults) {
            const analysis = `📊 **工具调用 ${res.toolCallId}**\n\`\`\`\n${res.output.slice(0, 200)}${res.output.length > 200 ? '...' : ''}\n\`\`\`\n\n根据输出内容，命令执行成功！全链路测试通过 ✨\n\n`;
            await this.streamText(analysis, callbacks, 10);
        }

        const summary = '如需继续测试，可以尝试:\n- 发送 "执行命令" 测试单个工具\n- 发送 "连续调用" 测试多个工具\n- 发送 "需要确认" 测试确认流程';
        await this.streamText(summary, callbacks, 15);
    }

    // ========================================
    // 场景处理方法
    // ========================================

    /**
     * 场景1: 命令执行测试
     */
    private async handleCommandScenario(text: string, callbacks: IAgentCallbacks): Promise<void> {
        const thinking = '🤔 我理解了，你想执行一个终端命令。让我来帮你...\n\n';
        await this.streamText(thinking, callbacks);
        
        await this.sleep(500);

        // 判断操作系统，生成合适的测试命令
        const isWindows = process.platform === 'win32';
        const testCommand = isWindows ? 'dir' : 'ls -la';
        
        const mockToolRequest: AgentToolRequest = {
            id: `call_${Date.now()}`,
            toolName: 'executeCommand', 
            toolArgs: { 
                command: testCommand,
                shell: isWindows ? 'powershell' : 'bash',
                cwd: process.cwd()
            }
        };

        callbacks.onToolRequest([mockToolRequest]);
    }

    /**
     * 场景2: 文件附件测试
     */
    private async handleFileScenario(
        text: string, 
        attachments: Attachment[] | undefined, 
        callbacks: IAgentCallbacks
    ): Promise<void> {
        if (!attachments || attachments.length === 0) {
            const noFiles = '📁 我注意到你提到了文件，但我没有看到任何附件。请先通过 📎 按钮添加文件。';
            await this.streamText(noFiles, callbacks);
            return;
        }

        let response = `📎 我看到你上传了 ${attachments.length} 个文件：\n\n`;
        attachments.forEach((file, idx) => {
            response += `${idx + 1}. **${file.name}**\n`;
            response += `   - 路径: \`${file.path}\`\n`;
            if (file.language) response += `   - 语言: ${file.language}\n`;
            if (file.size) response += `   - 大小: ${(file.size / 1024).toFixed(2)} KB\n`;
            response += '\n';
        });

        response += '文件信息已加载成功！这些文件将作为上下文用于后续对话。✨';
        await this.streamText(response, callbacks);
    }

    /**
     * 场景3: 多个工具连续调用
     */
    private async handleMultipleToolsScenario(callbacks: IAgentCallbacks): Promise<void> {
        const thinking = '🔄 好的，我将连续调用多个工具来完成这个任务...\n\n';
        await this.streamText(thinking, callbacks);

        await this.sleep(600);

        const isWindows = process.platform === 'win32';
        
        const toolRequests: AgentToolRequest[] = [
            {
                id: `call_${Date.now()}_1`,
                toolName: 'executeCommand',
                toolArgs: {
                    command: isWindows ? 'echo "第一个命令"' : 'echo "First command"',
                    shell: isWindows ? 'powershell' : 'bash'
                }
            },
            {
                id: `call_${Date.now()}_2`,
                toolName: 'executeCommand',
                toolArgs: {
                    command: isWindows ? 'echo "第二个命令"' : 'pwd',
                    shell: isWindows ? 'powershell' : 'bash'
                }
            }
        ];

        callbacks.onToolRequest(toolRequests);
    }

    /**
     * 场景4: 需要确认的工具调用
     */
    private async handleConfirmationScenario(callbacks: IAgentCallbacks): Promise<void> {
        const thinking = '⚠️ 这个操作需要你的确认。我准备执行一个需要权限的命令...\n\n';
        await this.streamText(thinking, callbacks);

        await this.sleep(500);

        const mockToolRequest: AgentToolRequest = {
            id: `call_confirm_${Date.now()}`,
            toolName: 'executeCommand',
            toolArgs: {
                command: 'echo "这是一个需要确认的操作"',
                shell: process.platform === 'win32' ? 'powershell' : 'bash'
            }
        };

        callbacks.onToolRequest([mockToolRequest]);
    }

    /**
     * 场景5: 普通对话
     */
    private async handleNormalConversation(text: string, callbacks: IAgentCallbacks): Promise<void> {
        const responseText = `你好！我是 Mock Agent 测试服务 🤖

**你发送的消息**: "${text}"

**可用的测试场景**:
1. 💻 发送包含 "命令"/"command" 的消息 → 测试工具调用
2. 📁 发送包含 "文件" 的消息 → 测试附件处理
3. 🔄 发送包含 "连续"/"多个" 的消息 → 测试多工具调用
4. ✅ 发送包含 "确认" 的消息 → 测试确认流程
5. 💬 其他消息 → 普通对话模式

**当前对话轮数**: ${this.conversationHistory.length}

试试看吧！✨`;

        await this.streamText(responseText, callbacks, 25);
    }

    // ========================================
    // 工具方法
    // ========================================

    /**
     * 流式输出文本
     */
    private async streamText(text: string, callbacks: IAgentCallbacks, delay: number = 20): Promise<void> {
        for (const char of text) {
            await this.sleep(delay);
            callbacks.onChunk(char);
        }
    }

    private sleep(ms: number) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}